From 70152d800313e0db1c4112e0debed960e058335e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 17 Jul 2015 10:05:57 -0700 Subject: [PATCH] Only compile activated optional dependencies Development dependencies are traversed during the resolution process, causing them to be returned as the list of dependencies for a package in terms of resolution. The compilation phase would then filter these out depending on the dependency's transitivity, but this was incorrectly accounted for when the dependency showed up multiple times in a few lists. This commit fixes this behavior by updating the filtering logic to ensure that only activated optional dependencies (those whose feature names are listed) are compiled. Closes #1805 --- src/cargo/ops/cargo_rustc/context.rs | 10 ++++++++-- tests/test_cargo_features.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 26b4a14c0..2782213dd 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -351,7 +351,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> { pkg.dependencies().iter().filter(|d| { d.name() == dep.name() }).any(|d| { - // If this target is a build command, then we only want build // dependencies, otherwise we want everything *other than* build // dependencies. @@ -364,7 +363,14 @@ impl<'a, 'cfg> Context<'a, 'cfg> { target.is_example() || profile.test; - is_correct_dep && is_actual_dep + // If the dependency is optional, then we're only activating it + // if the corresponding feature was activated + let activated = !d.is_optional() || + self.resolve.features(pkg.package_id()).map(|f| { + f.contains(d.name()) + }).unwrap_or(false); + + is_correct_dep && is_actual_dep && activated }) }).filter_map(|pkg| { pkg.targets().iter().find(|t| t.is_lib()).map(|t| { diff --git a/tests/test_cargo_features.rs b/tests/test_cargo_features.rs index 3d86dcedf..33a058f0e 100644 --- a/tests/test_cargo_features.rs +++ b/tests/test_cargo_features.rs @@ -741,3 +741,31 @@ test!(unions_work_with_no_default_features { assert_that(p.cargo("build"), execs().with_status(0).with_stdout("")); assert_that(p.cargo("build"), execs().with_status(0).with_stdout("")); }); + +test!(optional_and_dev_dep { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "test" + version = "0.1.0" + authors = [] + + [dependencies] + foo = { path = "foo", optional = true } + [dev-dependencies] + foo = { path = "foo" } + "#) + .file("src/lib.rs", "") + .file("foo/Cargo.toml", r#" + [package] + name = "foo" + version = "0.1.0" + authors = [] + "#) + .file("foo/src/lib.rs", ""); + + assert_that(p.cargo_process("build"), + execs().with_status(0).with_stdout(format!("\ +{compiling} test v0.1.0 ([..]) +", compiling = COMPILING))); +}); -- 2.30.2